﻿using System;
using System.Data;
using System.Runtime.Remoting;
using System.Windows.Forms;
using BDElectron.Remote;
using BDElectron.Platform;
using BDElectron.ClientSession;
using System.Xml;

namespace BDElectron.Client
{
    public partial class LoghinForm : Form
    {
        object mServerObject = null;
        IClientSession mClientSession = null;
        string mLogin = string.Empty;
        string mPassword = string.Empty;
        string mServerName = string.Empty;
        string mServersKey = "servers";
        string mServerKey = "server";
        string mServersFileName = "Servers.xml";
        string mUrlAttribute = "url";
        string mNameAttribute = "name";

        public object ServerObject
        {
            get  { return mServerObject; }
        }

        public string ServerName
        {
            get  { return mServerName; }
        }

        public LoghinForm()
        {
            InitializeComponent();
        }

        private void okButton_Click(object sender, EventArgs e)
        {
            statusLabel.Text = "Connecting...";
            Update();

            string serverName = serverSelectorComboBox.SelectedItem.ToString();
            string serverUrl = ServerUrlByServerName(serverName);
            mServerObject = (IServerObject)Activator.GetObject(typeof(IServerObject), serverUrl);

            mClientSession = (IClientSession)Activator.GetObject(typeof(IClientSession), serverUrl);
            if (mClientSession != null)
            {
                try
                {
                    mPassword = mClientSession.GetMd5Hash(mPassword);
                    mServerObject = mClientSession.GetServerObjectThoughAuthentication(mLogin, mPassword);                 

                    if (mServerObject != null )
                    {
                        statusLabel.Text = "Success!";
                        Update();
                        int millisecondsToSleep = 500;
                        System.Threading.Thread.Sleep(millisecondsToSleep);

                        mServerName = serverName;
                        this.DialogResult = System.Windows.Forms.DialogResult.OK;
                        Close();
                    }
                    else
                    {
                        statusLabel.Text = "Login failed.";
                    }
                }
                catch (Exception exception)
                {
                    statusLabel.Text = "Error: " + exception.Message;
                }
            }
            else
            {
                statusLabel.Text = "Unable to login, null Client Session object provided";
            }

            Update();
        }

        private void userTextBox_TextChanged(object sender, EventArgs e)
        {
            mLogin = userTextBox.Text.Trim();
            statusLabel.Text = string.Empty;
        }

        private void passwordTextBox_TextChanged(object sender, EventArgs e)
        {
            mPassword = passwordTextBox.Text.Trim();
            statusLabel.Text = string.Empty;
        }

        private void LoghinForm_Load(object sender, EventArgs e)
        {
            LoadServersList();
            serverSelectorComboBox.SelectedIndex = -1;
            statusLabel.Text = string.Empty;
            mPassword = string.Empty;
            mLogin = string.Empty;
        }

        private void LoadServersList()
        {
            serverSelectorComboBox.Items.Clear();

            // Load servers list document
            XmlDocument serversXml = new XmlDocument();
            loadServersListXml(serversXml);

            // read servers list and add in combo 
            XmlNode node = serversXml.SelectSingleNode("//" + mServersKey);
            if (node != null && node.HasChildNodes)
            {
                XmlNodeList serversNodeList = node.ChildNodes;
                for (int i = 0; i < serversNodeList.Count; i++)
                {
                    XmlNode serverNode = serversNodeList[i];
                    string name = serverNode.Attributes[mNameAttribute].Value;
                    string url = serverNode.Attributes[mUrlAttribute].Value;

                    string entry = name;

                    serverSelectorComboBox.Items.Add(entry);
                }
            }
        }

        private XmlDocument loadServersListXml(XmlDocument serversXmlDocument)
        {
            // Find the servers config file
            // Load servers config in xml doc            
            string appDir = AppDomain.CurrentDomain.BaseDirectory;
            string fileFullName = appDir + System.IO.Path.DirectorySeparatorChar + mServersFileName;
            if (!System.IO.File.Exists(fileFullName))
            {
                XmlDeclaration declarationEntry = serversXmlDocument.CreateXmlDeclaration("1.0", "utf-8", string.Empty);
                serversXmlDocument.AppendChild(declarationEntry);

                XmlElement entry = serversXmlDocument.CreateElement(mServersKey);
                serversXmlDocument.AppendChild(entry);
                serversXmlDocument.Save(fileFullName);
            }

            serversXmlDocument.Load(mServersFileName);
            return serversXmlDocument;
        }

        private string ServerUrlByServerName(string serverName)
        {
            string serverUrl = string.Empty;
            // Load servers list document
            XmlDocument serversXml = new XmlDocument();
            loadServersListXml(serversXml);

            XmlNode serversListNode = serversXml.SelectSingleNode("/" + mServersKey);

            // XPath select setting element that contains this key    
            XmlElement entry = (XmlElement)serversListNode.SelectSingleNode("//" + mServerKey + "[@name='" + serverName + "']");
            if (entry != null)
            {
                serverUrl = entry.GetAttribute("url");
            }

            return serverUrl;
        }

    }
}
